package com.peng.community.controller;

import com.alibaba.fastjson.JSONObject;
import com.peng.community.constant.CommunityConstant;
import com.peng.community.entity.Message;
import com.peng.community.entity.Page;
import com.peng.community.entity.User;
import com.peng.community.event.EventConsumer;
import com.peng.community.service.UserService;
import com.peng.community.service.impl.MessageService;
import com.peng.community.util.CommunityUtils;
import com.peng.community.util.HostHolder;
import lombok.extern.slf4j.Slf4j;
import org.apache.kafka.common.protocol.types.Field;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.util.HtmlUtils;

import java.util.*;
import java.util.stream.Collectors;

@Controller
@Slf4j
public class MessageController implements CommunityConstant {

    @Autowired
    MessageService messageService;

    @Autowired
    HostHolder hostHolder;

    @Autowired
    UserService userService;

    @GetMapping("/letter/list")
    public String getLettersList(Model model, Page page) {
        User user = hostHolder.getUser();
        page.setPath("/letter/list");
        page.setRows(messageService.selectConversationsCount(user.getId()));
        page.setLimit(5);

        List<Message> messages = messageService.selectConversations(user.getId(), page.getOffset(), page.getLimit());
        //vo列表
        List<Map<String, Object>> conversations = new ArrayList<>();

        if (messages != null) {
            for (Message message : messages) {
                Map<String, Object> conversation = new HashMap<>();
                conversation.put("conversation",message);
                conversation.put("conversationCount", messageService.selectLetterCount(message.getConversationId()));
                int targetId = message.getFromId() == user.getId() ? message.getToId() : message.getFromId();
                conversation.put("target", userService.findUserById(targetId));
                conversation.put("unreadCount", messageService.selectLetterUnreadCount(user.getId(),message.getConversationId()));
//                log.info"用户{}未读数量:{}", ((User)conversation.get("target")).getUsername(),conversation.get("unreadCount"));
                conversations.add(conversation);
            }
        }
        model.addAttribute("conversations", conversations);
        //添加所有的未读消息数量
        model.addAttribute("letterUnreadCount", messageService.selectLetterUnreadCount(user.getId(), null));

        int noticeUnreadCount = messageService.findNoticeUnreadCount(user.getId(), null);
        model.addAttribute("noticeUnreadCount", noticeUnreadCount);


        return "/site/letter";
    }

    @GetMapping("/letter/detail/{conversationId}")
    public String getLetterDetail(@PathVariable("conversationId")String conversationId, Model model, Page page) {
        page.setRows(messageService.selectLetterCount(conversationId));
        page.setLimit(5);
        page.setPath("/letter/detail/" + conversationId);

        List<Message> letters = messageService.selectLetters(conversationId, page.getOffset(), page.getLimit());
        List<Map<String, Object>> messages = new ArrayList<>();
        for (Message letter : letters) {
            Map<String, Object> message = new HashMap<>();
            message.put("letter", letter);
            message.put("fromUser", userService.findUserById(letter.getFromId()));
            messages.add(message);
        }
        model.addAttribute("letters", messages);
        model.addAttribute("target", getTarget(conversationId));

        //将所有未读消息更新为已读
        List<Integer> readed = getReadedMessageIds(letters);
        if (!readed.isEmpty()) {
            messageService.readMessages(readed);
        }
        return "/site/letter-detail";
    }

    private List<Integer> getReadedMessageIds(List<Message> letters) {
        List<Integer> res = new ArrayList<>();
        if (letters != null) {
            User user = hostHolder.getUser();
            for (Message letter : letters) {
                if (letter.getToId() == user.getId()) {
                    res.add(letter.getId());
                }
            }
        }
        return res;
    }

    private User getTarget(String conversationId) {
        String[] ids = conversationId.split("_");
        int id1 = Integer.parseInt(ids[0]), id2 = Integer.parseInt(ids[1]);
        int id = hostHolder.getUser().getId() ==  id1 ? id2 : id1;
        return userService.findUserById(id);
    }

    @PostMapping("/letter/send")
    @ResponseBody //异步请求
    public String sendMessage(String toName, String content) {
        User toUser = userService.findUserByUsername(toName);
        if (toUser == null) {
            return CommunityUtils.toJsonString(1, "您发送消息的用户不存在");
        }
        Message message = new Message();
        message.setContent(content);
        message.setToId(toUser.getId());
        User fromUser = hostHolder.getUser();
        message.setFromId(fromUser.getId());
        message.setCreateTime(new Date());
        if (message.getFromId() < message.getToId()) {
            message.setConversationId(message.getFromId() + "_" + message.getToId());
        } else {
            message.setConversationId(message.getToId() + "_" + message.getFromId());
        }
        messageService.insertMessage(message);

        return CommunityUtils.toJsonString(0,"发送成功!");
    }

    @RequestMapping(path = "/notice/list", method = RequestMethod.GET)
    public String getNoticeList(Model model) {
        User user = hostHolder.getUser();

        // 查询评论类通知
        Message message = messageService.findLatestNotice(user.getId(), TOPIC_COMMENT);
        if (message != null) {
            Map<String, Object> messageVO = new HashMap<>();
            messageVO.put("message", message);

            String content = HtmlUtils.htmlUnescape(message.getContent());
            Map<String, Object> data = JSONObject.parseObject(content, HashMap.class);

            messageVO.put("user", userService.findUserById((Integer) data.get("userId")));
            messageVO.put("entityType", data.get("entityType"));
            messageVO.put("entityId", data.get("entityId"));
            messageVO.put("postId", data.get("postId"));

            int count = messageService.findNoticeCount(user.getId(), TOPIC_COMMENT);
            messageVO.put("count", count);

            int unread = messageService.findNoticeUnreadCount(user.getId(), TOPIC_COMMENT);
            messageVO.put("unread", unread);

            log.error("消息未读数量{}", unread);
            if (messageVO.isEmpty()) {
                messageVO.put("message",null);
            }
            model.addAttribute("commentNotice", messageVO);
        }
//        log.info("comment:{}", messageVO);


        // 查询点赞类通知
        message = messageService.findLatestNotice(user.getId(), TOPIC_LIKE);
        if (message != null) {
            Map<String, Object> messageVO = new HashMap<>();

            messageVO.put("message", message);

            String content = HtmlUtils.htmlUnescape(message.getContent());
            Map<String, Object> data = JSONObject.parseObject(content, HashMap.class);

            messageVO.put("user", userService.findUserById((Integer) data.get("userId")));
            messageVO.put("entityType", data.get("entityType"));
            messageVO.put("entityId", data.get("entityId"));
            messageVO.put("postId", data.get("postId"));

            int count = messageService.findNoticeCount(user.getId(), TOPIC_LIKE);
            messageVO.put("count", count);

            int unread = messageService.findNoticeUnreadCount(user.getId(), TOPIC_LIKE);
            messageVO.put("unread", unread);
            if (messageVO.isEmpty()) {
                messageVO.put("message",null);
            }
            model.addAttribute("likeNotice", messageVO);
        }

//        log.info("like:{}", messageVO);

        // 查询关注类通知
        message = messageService.findLatestNotice(user.getId(), TOPIC_FOLLOW);
        if (message != null) {
            Map<String, Object> messageVO = new HashMap<>();

            messageVO.put("message", message);

            String content = HtmlUtils.htmlUnescape(message.getContent());
            Map<String, Object> data = JSONObject.parseObject(content, HashMap.class);

            messageVO.put("user", userService.findUserById((Integer) data.get("userId")));
            messageVO.put("entityType", data.get("entityType"));
            messageVO.put("entityId", data.get("entityId"));

            int count = messageService.findNoticeCount(user.getId(), TOPIC_FOLLOW);
            messageVO.put("count", count);

            int unread = messageService.findNoticeUnreadCount(user.getId(), TOPIC_FOLLOW);
            messageVO.put("unread", unread);

            if (messageVO.isEmpty()) {
                messageVO.put("message",null);
            }

            model.addAttribute("followNotice", messageVO);
        }



        // 查询未读消息数量
        int letterUnreadCount = messageService.selectLetterUnreadCount(user.getId(), null);
        model.addAttribute("letterUnreadCount", letterUnreadCount);
        int noticeUnreadCount = messageService.findNoticeUnreadCount(user.getId(), null);
        model.addAttribute("noticeUnreadCount", noticeUnreadCount);

//        log.info("follow:{}", messageVO);


        return "/site/notice";
    }

    @GetMapping("/notice/detail2/{topic}")
    public String getNoticeDetail(@PathVariable("topic")String topic, Model model, Page page) {
        User user = hostHolder.getUser();

        page.setLimit(5);
        page.setRows(messageService.findNoticeCount(user.getId(), topic));
        page.setPath("/notice/detail/" + topic);

        List<Message> notices = messageService.findNotices(user.getId(), topic, page.getOffset(), page.getLimit());
        List<Map<String, Object>> noticeVos = new ArrayList<>();

        for (Message notice : notices) {
            Map<String, Object> map = new HashMap<>();
            Map<String, Object> content = JSONObject.parseObject(HtmlUtils.htmlUnescape(notice.getContent()), Map.class);
            map.put("notice", notice);
            map.put("postId", content.get("postId"));
            map.put("entityType",content.get("entityType"));
            map.put("entityId",content.get("entityId"));
            map.put("user", userService.findUserById((Integer) content.get("userId")));

            //通知的发出者（系统）
            map.put("fromUser",userService.findUserById(notice.getFromId()));
            noticeVos.add(map);
        }
        model.addAttribute("notices",noticeVos);

        //设置当前消息已读
        List<Integer> ids = getReadedMessageIds(notices);
        if (!ids.isEmpty()) {
            messageService.readMessages(ids);
        }

        return "/site/notice-detail";
    }

    @RequestMapping(path = "/notice/detail/{topic}", method = RequestMethod.GET)
    public String getNoticeDetail(@PathVariable("topic") String topic, Page page, Model model) {
        User user = hostHolder.getUser();

        page.setLimit(5);
        page.setPath("/notice/detail/" + topic);
        page.setRows(messageService.findNoticeCount(user.getId(), topic));

        List<Message> noticeList = messageService.findNotices(user.getId(), topic, page.getOffset(), page.getLimit());
        List<Map<String, Object>> noticeVoList = new ArrayList<>();
        if (noticeList != null) {
            for (Message notice : noticeList) {
                Map<String, Object> map = new HashMap<>();
                // 通知
                map.put("notice", notice);
                // 内容
                String content = HtmlUtils.htmlUnescape(notice.getContent());
                Map<String, Object> data = JSONObject.parseObject(content, HashMap.class);
                map.put("user", userService.findUserById((Integer) data.get("userId")));
                map.put("entityType", data.get("entityType"));
                map.put("entityId", data.get("entityId"));
                map.put("postId", data.get("postId"));
                // 通知作者
                map.put("fromUser", userService.findUserById(notice.getFromId()));

                noticeVoList.add(map);
            }
        }
        model.addAttribute("notices", noticeVoList);

        // 设置已读
        List<Integer> ids = getLetterIds(noticeList);
        List<Integer> collect = noticeList.stream().map(Message::getId).collect(Collectors.toList());
        log.info("全部的消息:{}",collect.toString());
        log.info("读取的消息:{}",ids.toString());
        if (!ids.isEmpty()) {
            messageService.readMessages(ids);
        }

        return "/site/notice-detail";
    }

    private List<Integer> getLetterIds(List<Message> letterList) {
        List<Integer> ids = new ArrayList<>();

        if (letterList != null) {
            for (Message message : letterList) {
                if (hostHolder.getUser().getId() == message.getToId() && message.getStatus() == 0) {
                    ids.add(message.getId());
                }
            }
        }

        return ids;
    }
}

